//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
#include <windows.h>
#include <pehdr.h>
#include <romLdr.h>
#include <oal.h>
#include <bootStore.h>
#include <bootStoreUtils.h>

//------------------------------------------------------------------------------

BOOL
BootStoreGetBinFsInfo(
    HANDLE hStore,
    UINT32 *pBase,
    UINT32 *pSize
    )
{
    BOOL rc = FALSE;
    UINT64 oldPos = -1;
    UINT32 info[3];
    ROMHDR romHdr;


    // First save old position
    if (!BootStoreGetPos(hStore, &oldPos))
        {
        OALMSG(OAL_ERROR, (L"ERROR: BootStoreGetBinFsInfo: "
            L"Failed get actual stream position!\r\n"
            ));
        goto cleanUp;
        }

    // Seek to signature
    if (!BootStoreSeek(hStore, ROM_SIGNATURE_OFFSET))
        {
        OALMSG(OAL_WARN, (L"BootStoreGetBinFsInfo: "
            L"Failed seek to ROM_SIGNATURE_OFFSET!\r\n"
            ));
        goto cleanUp;
        }

    // Read signature and 2 pointers
    if (sizeof(info) != BootStoreRead(hStore, info, sizeof(info)))
        {
        OALMSG(OAL_WARN, (L"BootStoreGetBinFsInfo: "
            L"Failed read signature and offsets!\r\n"
            ));
        goto cleanUp;
        }

    // Check CE signature
    if (info[0] != ROM_SIGNATURE)
        {
        OALMSG(OAL_WARN, (L"BootStoreGetBinFsInfo: "
            L"BinFS signature wasn't found!\r\n"
            ));
        goto cleanUp;
        }

    // Seek to ROMHDR
    if (!BootStoreSeek(hStore, info[2]))
        {
        OALMSG(OAL_WARN, (L"BootStoreGetBinFsInfo: "
            L"Failed seek to ROMHDR position 0x%08x!\r\n", info[2]
            ));
        goto cleanUp;
        }

    // Read it
    if (sizeof(romHdr) != BootStoreRead(hStore, &romHdr, sizeof(romHdr)))
        {
        OALMSG(OAL_WARN, (L"BootStoreGetBinFsInfo: "
            L"Failed read ROMHDR structure!\r\n"
            ));
        goto cleanUp;
        }

    // Set image address and size
    if (pBase != NULL) *pBase = romHdr.physfirst;
    if (pSize != NULL) *pSize = romHdr.physlast - romHdr.physfirst;
    
    // Done
    rc = TRUE;
    
cleanUp:
    if (oldPos != -1) BootStoreSeek(hStore, oldPos);
    return rc;
}

//------------------------------------------------------------------------------
